﻿using System.Collections.Generic;
using OMC.AddInHandling;
using OMC.Classification;
using Core = Microsoft.Office.Core;
using Outlook = Microsoft.Office.Interop.Outlook;
using System.Threading;
using Settings = OMC.Properties.Settings;
using System;

namespace OMC.DataManagement
{
    /// <summary>
    /// An object of this class could manage all the things about the
    /// handling of the Add-In.
    /// </summary>
    class Manager
    {
        private List<Folder> folderList;
        private List<MenuItem> predictedFolderList;
        private AddInHandler addInHandler { get; set; }
        private ClassificationHandler classificationHandler { get; set; }
        private MailContent selectedMailItemContent;
        private Outlook.Accounts accounts;
        private bool isDataSetLoaded = false;

        /// <summary>
        /// The constructor to create a object.
        /// </summary>
        /// <param name="accounts">actual outlook accounts</param>
        /// <param name="explorer">actual outlook explorer</param>
        public Manager(Outlook.Accounts accounts, Outlook.Explorer explorer)
        {
            folderList = new List<Folder>();
            addInHandler = new AddInHandler(explorer, accounts, this);
            classificationHandler = new ClassificationHandler();
            this.accounts = accounts;
            predictedFolderList = new List<MenuItem>();
            LoadCustomProperties();
        }

        /// <summary>
        /// This Method sets the custom properties to application and
        /// make a refresh of the dataset.
        /// </summary>
        public void LoadCustomProperties()
        {
            MailContent.SetUseStopwords(Settings.Default.luceneAnalyzer);
            classificationHandler.SetClassifier(Settings.Default.classifierIndex);
            this.Load();
        }

        /// <summary>
        /// This Method loads the dataset of outlook.
        /// </summary>
        public void Load()
        {
            //load Dataset at first use
            Thread thread = new Thread(new ThreadStart(LoadDataSet));
            thread.Start();
        }

        /// <summary>
        /// This Mehtod loads the mail dataset.
        /// </summary>
        private void LoadDataSet()
        {
            isDataSetLoaded = false;

            //Clear all
            folderList.Clear();
            classificationHandler.Clear();

            //load Mail Data
            folderList = addInHandler.LoadMailData();
            classificationHandler.CreateInstances(folderList);

            //Train Classifier
            classificationHandler.TrainClassifier();

            //Set up
            isDataSetLoaded = true;
        }

        /// <summary>
        /// This method saves dataset to ARFF file.
        /// </summary>
        /// <param name="filePath">the destination path inkl file name</param>
        /// <param name="isFiltered">
        /// true, the arff file is filtered with the StringToWord filter
        /// false, the arff file isn't filtered, it's possible to read the content of it
        /// </param>
        public void SaveToFile(string filePath, bool isFiltered)
        {
            classificationHandler.WriteInstance(filePath, isFiltered);
        }

        /// <summary>
        /// This method handle the right click event of a mail item.
        /// </summary>
        /// <param name="commandBar">this Commandbar could be modified</param>
        /// <param name="selection">this Selection could be use to determine the Mailitem</param>
        public void contextMenuDisplay(Core.CommandBar commandBar, Outlook.Selection selection)
        {
            if (selection != null)
            {
                if (selection.Count == 1)
                {
                    object selectedItem = selection[1];
                    if (selectedItem is Outlook.MailItem)
                    {
                        Outlook.MailItem mailItem = selectedItem as Outlook.MailItem;
                        if (mailItem != null)
                        {
                            //Create context popup menu
                            addInHandler.MakeContextPopUp(commandBar);

                            //load selected Maildata an create a MailContent object
                            selectedMailItemContent = new MailContent(mailItem.Body,
                                                                      mailItem.Subject,
                                                                      mailItem.SenderEmailAddress,
                                                                      mailItem.To);

                            if (!isDataSetLoaded)
                            {
                                return;
                            }

                            //clear Predicted Folder list
                            predictedFolderList.Clear();

                            //Classify selected item
                            predictedFolderList = classificationHandler.Classify(selectedMailItemContent, folderList);

                            //Create the Context Menu
                            addInHandler.MakeContextMenuButtons(commandBar, predictedFolderList, mailItem);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Is the data set loaded?
        /// </summary>
        /// <returns>true if the dataset has been loaded</returns>
        public bool IsDataSetLoaded()
        {
            return isDataSetLoaded;
        }
    }
}